﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;

namespace StairsModuleAndEdit.StairsModel.CommonUnit
{
	public class ElementGeometryFaceManager
	{
		public static List<Face> GetEleAllPlanarFace(Element ele)
		{
			List<Face> list = new List<Face>();
			Options options = new Options();
			GeometryElement geomElem = ele.get_Geometry(options);
			List<Solid> geometryElementSolid = ElementGeometryFaceManager.GetGeometryElementSolid(geomElem);
			foreach (Solid solid in geometryElementSolid)
			{
				foreach (object obj in solid.Faces)
				{
					Face face = (Face)obj;
					if (face is PlanarFace)
					{
						list.Add(face);
					}
				}
			}
			return list;
		}

		public static Face GetTopMostPlanarFace(Element ele)
		{
			Face result = null;
			List<Face> eleAllPlanarFace = ElementGeometryFaceManager.GetEleAllPlanarFace(ele);
			double val = double.MinValue;
			foreach (Face face in eleAllPlanarFace)
			{
				XYZ xyz = face.ComputeNormal(UV.Zero);
				if (!Geometry.Lessthan_Or_Equal(xyz.Z, 0.0))
				{
					double faceHeight = ElementGeometryFaceManager.GetFaceHeight(face);
					if (Geometry.GreaterThan(faceHeight, val))
					{
						result = face;
						val = faceHeight;
					}
				}
			}
			return result;
		}

		private static List<Solid> GetGeometryElementSolid(GeometryElement geomElem)
		{
			List<Solid> list = new List<Solid>();
			if (null == geomElem)
			{
				return list;
			}
			foreach (GeometryObject geometryObject in geomElem)
			{
				Type type = geometryObject.GetType();
				if (type == typeof(GeometryInstance))
				{
					GeometryInstance geometryInstance = geometryObject as GeometryInstance;
					GeometryElement instanceGeometry = geometryInstance.GetInstanceGeometry();
					list.AddRange(ElementGeometryFaceManager.GetGeometryElementSolid(instanceGeometry));
				}
				else if (type == typeof(Solid))
				{
					Solid solid = geometryObject as Solid;
					if (null != solid)
					{
						list.Add(solid);
					}
				}
			}
			return list;
		}

		private static double GetFaceHeight(Face face)
		{
			double result = 0.0;
			if (null == face)
			{
				return result;
			}
			bool flag = false;
			foreach (object obj in face.EdgeLoops)
			{
				EdgeArray edgeArray = (EdgeArray)obj;
				foreach (object obj2 in edgeArray)
				{
					Edge edge = (Edge)obj2;
					XYZ xyz = edge.Evaluate(0.0);
					if (xyz != null)
					{
						result = xyz.Z;
						flag = true;
						break;
					}
				}
				if (flag)
				{
					break;
				}
			}
			return result;
		}
	}
}
